package edu.albany.assassin;

import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.util.FloatMath;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MapActivity;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

public class GameMapsActivity extends MapActivity implements LocationListener {
	String contextService = Context.LOCATION_SERVICE;
	private static final String TAG = "GpsActivity";
	private GeoPoint geoPoint1;
	private GeoPoint geoPoint;

	private TextView distance = null;
	LocationManager locationManager;
	Location currentLocation;
	MapController mapController;
	MapView mapView;
	GeoPoint currentPoint;
	MyLocationOverlay myOverLay;

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		locationManager.removeUpdates(this);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.game_maps);
		distance = (TextView) findViewById(R.id.distance);
		mapView = (MapView) findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(true);
		mapView.setEnabled(true);
		mapView.setClickable(true);
		mapController = mapView.getController();
		myOverLay = new MyLocationOverlay();
		Timer myTimer = new Timer();
		// List<Overlay> overlays = mapView.getOverlays();
		// overlays.add(myOverLay);
		geoPoint1 = new GeoPoint((int) 42687293, (int) -73824660);
		/*
		 * int c=0; for(geoPoint = new GeoPoint((int)42686043,(int)-73822651)
		 * ;geoPoint.getLatitudeE6()!=geoPoint1.getLatitudeE6()&&
		 * geoPoint.getLongitudeE6()!=geoPoint1.getLongitudeE6();c++){
		 */
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686043, (int) -73822651);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686161, (int) -73822850);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686272, (int) -73822992);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686354, (int) -73823078);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686418, (int) -73823185);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686493, (int) -73823281);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686526, (int) -73823359);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686560, (int) -73823415);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686599, (int) -73823485);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686632, (int) -73823542);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686669, (int) -73823598);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686730, (int) -73823686);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686769, (int) -73823756);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686803, (int) -73823821);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686842, (int) -73823896);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686878, (int) -73823955);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686911, (int) -73824030);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42686964, (int) -73824099);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42687020, (int) -73824188);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42687067, (int) -73824263);
			}
		}, 0, 3000);
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {

				geoPoint = new GeoPoint((int) 42687293, (int) -73824660);

			}
		}, 0, 8000);

		mapController.setZoom(18);

		String provider = getBestProvider();

		currentLocation = locationManager.getLastKnownLocation(provider);
		if (currentLocation != null) {
			List<Overlay> overlays = mapView.getOverlays();
			overlays.add(myOverLay);
			setCurrentLocation(currentLocation);
			Log.e(TAG, currentLocation.toString());
		} else {
			Toast.makeText(this, "Location not yet acquired", Toast.LENGTH_LONG)
					.show();
		}

		animateToCurrentLocation();
		//
		// String provider=locationManager.getBestProvider(criteria, true);
		// Location location=locationManager.getLastKnownLocation(provider);
		//
		Log.e("animateToCurrentLocation", "animateToCurrentLocation is ok");
	}

	private double gps2m(float lat_a, float lng_a, float lat_b, float lng_b) {
		float pk = (float) (180 / 3.14169);

		float a1 = lat_a / pk;
		float a2 = lng_a / pk;
		float b1 = lat_b / pk;
		float b2 = lng_b / pk;

		float t1 = FloatMath.cos(a1) * FloatMath.cos(a2) * FloatMath.cos(b1)
				* FloatMath.cos(b2);
		float t2 = FloatMath.cos(a1) * FloatMath.sin(a2) * FloatMath.cos(b1)
				* FloatMath.sin(b2);
		float t3 = FloatMath.sin(a1) * FloatMath.sin(b1);
		double tt = Math.acos(t1 + t2 + t3);

		return 6366000 * tt;
	}

	public void animateToCurrentLocation() {
		if (currentPoint != null) {
			mapController.animateTo(currentPoint);
			mapController.setCenter(currentPoint);
		}
	}

	public String getBestProvider() {
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		Criteria criteria = new Criteria();

		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setSpeedRequired(false);
		criteria.setCostAllowed(false);
		criteria.setBearingRequired(false);
		criteria.setAltitudeRequired(false);
		criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);

		String bestProvider = locationManager.getBestProvider(criteria, true);
		return bestProvider;
	}

	public void setCurrentLocation(Location location) {
		int currLatitude = (int) (location.getLatitude() * 1E6);
		int currLongitude = (int) (location.getLongitude() * 1E6);
		currentPoint = new GeoPoint(currLatitude, currLongitude);

		// currentLocation = new Location("");
		currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6);
		currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6);
	}

	class MyLocationOverlay extends Overlay {

		private Location location;

		public void setLocation(Location location) {
			this.location = location;
		}

		@Override
		public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
				long when) {

			Projection projection = mapView.getProjection();

			Double latitude = currentLocation.getLatitude() * 1E6;
			Double longitude = currentLocation.getLongitude() * 1E6;

			super.draw(canvas, mapView, shadow);
			Paint paint = new Paint();
			Point point = new Point();
			// GeoPoint geoPoint = new
			// GeoPoint(latitude.intValue(),longitude.intValue());
			projection.toPixels(geoPoint, point);
			paint.setStrokeWidth(1);
			paint.setARGB(255, 255, 0, 0);
			paint.setStyle(Paint.Style.STROKE);
			Bitmap bmp = BitmapFactory.decodeResource(getResources(),
					R.drawable.enemy);
			canvas.drawBitmap(bmp, point.x, point.y, paint);
			canvas.drawText("YOUR ENEMY", point.x, point.y, paint);

			Paint paint1 = new Paint();
			Point myScreenCoords1 = new Point();
			// GeoPoint geoPoint1=new
			// GeoPoint((int)(location.getLatitude()*1E6),
			// (int)(location.getLongitude()*1E6));
			mapView.getProjection().toPixels(geoPoint1, myScreenCoords1);
			paint1.setStrokeWidth(1);
			paint1.setARGB(255, 255, 0, 0);
			paint1.setStyle(Paint.Style.STROKE);
			Bitmap bmp1 = BitmapFactory.decodeResource(getResources(),
					R.drawable.home);
			canvas.drawBitmap(bmp1, myScreenCoords1.x, myScreenCoords1.y,
					paint1);
			canvas.drawText("YOU  ARE  HERE", myScreenCoords1.x, myScreenCoords1.y,
					paint1);
			return true;

		}

	}

	public void onLocationChanged(Location newLocation) {
		setCurrentLocation(newLocation);
		animateToCurrentLocation();
	}

	public void onProviderDisabled(String arg0) {
		// TODO Auto-generated method stub
	}

	public void onProviderEnabled(String arg0) {
		// TODO Auto-generated method stub
	}

	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub
	}

	protected void onResume() {
		super.onResume();
		locationManager.requestLocationUpdates(getBestProvider(), 500, 1,
				(LocationListener) this);
	}

	protected void onPause() {
		super.onPause();
		locationManager.removeUpdates((LocationListener) this);
	}

	public void myClickHandler(View target) {
		switch (target.getId()) {
		case R.id.sat:
			mapView.setSatellite(true);
			mapView.setTraffic(false);
			break;
		case R.id.traffic:
			mapView.setTraffic(true);
			mapView.setSatellite(false);
			break;
		case R.id.normal:
			mapView.setSatellite(false);
			mapView.setTraffic(false);
			break;
		case R.id.kill:
			Intent intent = new Intent();
			intent.setClass(GameMapsActivity.this, WinPage.class);
			GameMapsActivity.this.startActivity(intent);
			break;
		case R.id.distance:
			distance.setText(""
					+ (double) (gps2m((float) 42.687293, (float) -73.824660,
							(float) currentLocation.getLatitude(),
							(float) currentLocation.getLongitude())));
			break;
		}

	}

	@Override
	protected boolean isLocationDisplayed() {
		return false;
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub

		if (keyCode == KeyEvent.KEYCODE_BACK) {
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Are you sure to quit this game?")
					.setCancelable(false)
					.setPositiveButton("Yes",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									GameMapsActivity.this.finish();
									android.os.Process
											.killProcess(android.os.Process
													.myPid());
									android.os.Process
											.killProcess(android.os.Process
													.myTid());
									android.os.Process
											.killProcess(android.os.Process
													.myUid());
								}
							})
					.setNegativeButton("Return",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									dialog.cancel();
								}
							});
			AlertDialog alert = builder.create();
			alert.show();
			return true;
		}

		return super.onKeyDown(keyCode, event);
	}
}
